Release 10.1A: OpenEdge Getting Started:
Object-oriented Programming


Defining methods within a class

Methods define the behavior of a class. Methods can access any data members of the class including non-private (PUBLIC or PROTECTED) data members of each super class in the class hierarchy. Methods are only valid in a class and cannot be defined in a procedure. Methods also require an access modifier that defines the scope of the method. The access modifiers are PRIVATE, PROTECTED, and PUBLIC. PRIVATE methods can only be accessed by the class that defines them. PROTECTED methods can be accessed by the class that defines them and by any class that inherits from that class. PUBLIC methods can be invoked by the class defining them, by any class that inherits from that class, and by any class or procedure that instantiates that class using an object reference. For more information, see the "Calling methods from outside a class" section.

A subclass can define a method using the same name as a method in its super class along with the OVERRIDE modifier. This new definition overrides the method of the same name in the super class. Only methods can be overridden not constructors or destructors. The method name, return type, number of parameters, and each corresponding parameter type must match between the super class method and the subclass method. In addition, the access modifier of the method should match. However, a PUBLIC subclass method can override a PROTECTED super class method, if you want. Any class that inherits from the subclass will inherit the method of the subclass and will not "see" the method of the super class. The subclass can access the method of the same name in the super class using the SUPER system reference. For more information on overriding methods, see the "Overriding methods" section.

A method can return a CHARACTER, CLASS, COM-HANDLE, DATE, DATETIME, DATETIME-TZ, DECIMAL, HANDLE, INTEGER, LONGCHAR, LOGICAL, MEMPTR, RAW, RECID, or ROWID; where CLASS is an object reference to a class. To return a specific value, use the RETURN statement from within the method. A method can also specify VOID as its return type, which means the method does not return a value. The code within a method is made up of Progress language statements much the same as in a procedure. Methods can also use the syntax described in this manual that is restricted to classes and cannot use certain syntax that is relevant only to procedures. For example, UPDATE, SET, PROMPT-FOR, CHOOSE, INSERT, WAIT-FOR, and READKEY statements are not permitted in a method with a return type. You also cannot use the RETURN ERROR statement.

A method in a class can run any external procedure using the standard RUN statement. It can also run an internal procedure or user-defined function using a procedure object handle.

Methods are of course very similar to the internal procedures and user-defined functions of a Progress procedure. Methods share some of the same restrictions of internal procedures and user-defined functions. When a method has a VOID return type, the methods can contain any statements allowed within an internal procedure. When the method returns a data type the method is limited to the set of statements allowed for user-defined functions. This limitation exists because methods with a return value can be used in an expression, and certain statements are not allowed during expression evaluation.

As in an internal procedure or user-defined function, local variables defined within methods are scoped to the method. Their values do not persist across method invocations but are re-initialized on every call to the method. If a local variable in a method has the same name as a data member for the class then the class's data member is shadowed by the local variable's definition. If a local variable definition in a method shadows a data member of the same name in its class or a super class, there is no way for the method to access the data member of the class.

The RETURN ERROR statement is not supported for methods. If you want to return error information to the caller of a method, you cannot invoke RETURN ERROR to raise the error condition in the caller. Instead, you can return this failure status to the caller using an output parameter. In addition, you can use NO-ERROR on specified statements to handle errors returned by statements within the method.

This is the syntax for a defining class method:

Syntax
METHOD { method-modifiers } { VOID | return-type } method-name  
       ( [ parameter [ , parameter ] ... ] ): 
        method-body  
END [ METHOD ] . 

Element descriptions for this syntax diagram follow:

method-modifiers

A list of options that modify the behavior of the method. They can appear in any order as specified in the following syntax:

Syntax
{ PRIVATE | PROTECTED | PUBLIC } [ OVERRIDE ] [ FINAL ] 

PRIVATE | PROTECTED | PUBLIC

This mandatory modifier defines the access mode for the method. PRIVATE methods can only be accessed by the class defining the method. PROTECTED methods can be accessed by the class defining them and by any class that inherits from that class. PUBLIC methods can be accessed by the class defining them, by any class that inherits from that class, and from other classes using an object reference.

OVERRIDE

This optional modifier means that this method overrides a method defined in a super class in the class hierarchy. The compiler verifies that this method and a method of the same name in a super class have the same return type, access mode, and number of parameters. Each parameter's corresponding mode and data type must also match in order. If any of these tests fail, the compiler generates an error. If you want, however, a PUBLIC subclass method can override a PROTECTED super class method.

FINAL

This optional modifier means that the method cannot be overridden. Any class that inherits from this class cannot define a method with the same method name as this method.

Note: The FINAL modifier is permitted but irrelevant on a PRIVATE method, or on any method within a class that itself has been defined as FINAL. A subclass can define a method with the same definition as a PRIVATE method in its super class. However in this case, the subclass has simply defined its own method and is not overriding the super class's method.

VOID | return-type

The return-type is the data type of the value returned by the method. The data types that can be returned by a method are the same data types supported for return values by user-defined functions: CHARACTER, CLASS, COM-HANDLE, DATE, DATETIME, DATETIME-TZ, DECIMAL, HANDLE, INTEGER, LONGCHAR, LOGICAL, MEMPTR, RAW, RECID, ROWID; where CLASS is an object reference to a class. The method can also return VOID which means the method does not return a value.

To set the return value for a method, you must use the RETURN statement with a value of the same data type as return-type. There is no implicit type conversion.

method-name

This is the name of the method. The method name must be unique within the class and cannot be the same as the class name. If the name is the same as the name of a non-private method in a super class within its class hierarchy, the subclass method overrides the method in the super class and must use the OVERRIDE option. If the signatures are not the same (see the OVERRIDE option), a compiler error is generated.

[ parameter [ , parameter ] ... ]

Any parameters that you define for the method. For more information on the syntax of parameter, see the “Parameter definition syntax” reference entry in OpenEdge Development: Progress 4GL Reference .

method-body

The method-body is all the logic of the method and can be composed of any Progress statements currently allowed within an internal procedure, plus the new syntax that is restricted to classes and their methods. If the method has a return type, the code you can use in the method is limited in the same way as for a user-defined function. For example, UPDATE, SET, PROMPT-FOR, CHOOSE, INSERT, WAIT-FOR, and READKEY statements are not permitted in a method with a return type.

In addition, you cannot use any statements or 4GL elements in the method-body that are only relevant in procedures, such as the RETURN ERROR statement or a reference to the THIS-PROCEDURE system handle.

Adding a method to our sample class definition results in this code:

CLASS acme.myObjs.CustObj INHERITS acme.myObjs.Common.CommonObj:  
    DEFINE PUBLIC VARIABLE iNumCusts AS INTEGER NO-UNDO. 
    DEFINE PROTECTED TEMP-TABLE ttCust NO-UNDO 
        FIELD CustNum LIKE Customer.CustNum 
        FIELD Name LIKE Customer.Name. 
    DEFINE PRIVATE VARIABLE rError  
        AS CLASS acme.myObjs.Common.ErrorObj NO-UNDO. 
    METHOD PUBLIC CHARACTER GetCustomerName(INPUT piCustNum AS INTEGER): 
        FIND ttCust WHERE ttCust.CustNum = piCustNum NO-ERROR. 
        IF AVAILABLE ttCust THEN 
            RETURN ttCust.CustName. 
        ELSE 
            RETURN ?. 
    END METHOD. 
END CLASS. 


Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095